package org.openinsula.arena.aws.integration.transformer;

import javax.annotation.Resource;

import org.openinsula.arena.aws.AwsConstants;
import org.openinsula.arena.aws.s3.S3Manager;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.integration.core.Message;
import org.springframework.integration.message.MessageBuilder;
import org.springframework.integration.transformer.MessageTransformationException;
import org.springframework.integration.transformer.Transformer;
import org.springframework.util.Assert;

/**
 * {@link Transformer} implementation that transforms a {@link String} payload
 * to a byte array payload obtained from a S3 object. The S3 bucket name is
 * provided in the {@link AwsConstants#S3_BUCKET_NAME} header, and the S3
 * resource name is provided in the {@link AwsConstants#S3_RESOURCE_NAME}.
 * 
 * @author Edson Yanaga
 */
public class StringToS3ObjectTransformer implements Transformer, InitializingBean {

	@Resource(name = "s3Manager")
	private S3Manager s3Manager;

	private String bucketName;

	@Override
	public void afterPropertiesSet() throws Exception {
		Assert.notNull(s3Manager, "'s3Manager' must not be null");
		Assert.notNull(bucketName, "'bucketName' must not be null");
	}

	@Override
	public Message<?> transform(Message<?> message) {
		if (message.getPayload() instanceof String) {
			String resourceName = (String) message.getPayload();

			try {
				byte[] data = s3Manager.get(bucketName, resourceName);

				return MessageBuilder.withPayload(data).setHeader(AwsConstants.S3_RESOURCE_NAME, resourceName).build();
			}
			catch (Exception e) {
				throw new MessageTransformationException(message, "failed to transform to a byte array message", e);
			}
		}
		else {
			throw new MessageTransformationException(message, String.format("%s requires a java.lang.String payload",
					this.getClass().getSimpleName()));
		}
	}

	public void setS3Manager(S3Manager s3Manager) {
		this.s3Manager = s3Manager;
	}

	public void setBucketName(String bucketName) {
		this.bucketName = bucketName;
	}

}
